import { isNilOrEmpty, notNilEmpty } from 'qx-util';
import { IPSModelObject } from './ipsmodel-object';
import { IPSModelService } from './ipsmodel-service';

export abstract class PSModelObjectImpl implements IPSModelObject {
  /**
   * 当前类名称
   *
   * @author chitanda
   * @date 2021-05-26 09:05:15
   * @readonly
   * @type {string}
   */
  get cls(): string {
    return 'PSModelObjectImpl';
  }

  /**
   * 标准模型数据
   *
   * @protected
   * @type {*}
   */
  protected _data: IModel = {};

  /**
   * 模型路径
   *
   * @protected
   * @type {string}
   */
  protected _modelFilePath!: string;

  /**
   * 是否已填充模型
   *
   * @author chitanda
   * @date 2021-04-11 15:04:14
   * @readonly
   * @type {boolean}
   */
  get isFill(): boolean {
    return notNilEmpty(this._data);
  }

  protected _id!: string;

  get id(): string {
    if (this._id) {
      return this._id;
    }
    return this.M.id;
  }

  get name(): string {
    return this.M.name;
  }

  get codeName(): string {
    return this.M.codeName;
  }

  get userTag(): string {
    return this.M.userTag;
  }

  get userTag2(): string {
    return this.M.userTag2;
  }

  get userTag3(): string {
    return this.M.userTag3;
  }

  get userTag4(): string {
    return this.M.userTag4;
  }

  get userCat(): string {
    return this.M.userCat;
  }

  get userParams(): IModel {
    return this.M.getUserParam;
  }

  get modelid(): string {
    return this.M.modelid;
  }

  get modeltype(): string {
    return this.M.modeltype;
  }

  get mosFilePath(): string {
    return this.M.mOSFilePath;
  }

  get rtMOSFilePath(): string {
    return this.M.rTMOSFilePath;
  }

  get dynaModelFilePath(): string {
    return this.M.dynaModelFilePath;
  }

  get mOSFilePath(): string {
    return this.M.mOSFilePath;
  }

  /**
   * 模型服务
   *
   * @protected
   * @type {IPSModelService}
   */
  protected iPSModelService!: IPSModelService;

  /**
   * 父模型
   *
   * @protected
   * @type {IPSModelObject}
   */
  protected parentModel?: IPSModelObject;

  get parent(): IPSModelObject {
    return this.parentModel!;
  }

  /**
   * 标准模型
   *
   * @readonly
   * @type {IModel}
   */
  get M(): IModel {
    return this._data;
  }

  /**
   * 模型文件路径
   *
   * @author chitanda
   * @date 2021-04-08 16:04:16
   * @readonly
   * @type {string}
   */
  get modelFilePath(): string {
    return this._modelFilePath;
  }

  /**
   * 模型标识路径
   *
   * @author chitanda
   * @date 2021-04-08 16:04:08
   * @readonly
   * @type {string}
   */
  get modelPath(): string {
    return this._data.path || this._data.dynaModelFilePath || this.modelFilePath;
  }

  /**
   * 初始化
   *
   * @author chitanda
   * @date 2021-12-26 16:12:44
   * @param {IPSModelService} iPSModelService 模型服务
   * @param {string} modelPath 模型路径
   * @param {IModel} [model] 模型
   * @param {IPSModelObject} [parentModel] 父模型对象
   */
  init(iPSModelService: IPSModelService, modelPath: string, model?: IModel, parentModel?: IPSModelObject) {
    this.iPSModelService = iPSModelService;
    this._modelFilePath = modelPath;
    if (parentModel) {
      this.parentModel = parentModel;
    }
    if (model != null) {
      this._data = model;
      // 设置模型为不可修改，减少内存引用
      Object.freeze(this._data);
      this.calcId();
    }
    this.onInit();
  }

  protected onInit(): void {}

  /**
   * 计算模型唯一标识
   *
   * @author chitanda
   * @date 2021-07-27 16:07:04
   * @protected
   */
  protected calcId() {
    if (isNilOrEmpty(this._id)) {
      if (notNilEmpty(this.modelPath)) {
        this._id = this.modelPath!;
      } else if (notNilEmpty(this.id)) {
        this._id = this.id;
      } else if (notNilEmpty(this.codeName)) {
        this._id = this.codeName;
      } else if (notNilEmpty(this.name)) {
        this._id = this.name;
      }
    }
  }

  /**
   * 获取模型服务
   *
   * @return {*}  {IPSModelService}
   */
  getPSModelService(): IPSModelService {
    return this.iPSModelService;
  }

  /**
   * 判断是否实现某接口，子类中发布
   *
   * @param {string} _cls
   * @return {*}  {boolean}
   */
  instanceof(_cls: string): boolean {
    return false;
  }

  /**
   * 从模型节点中获取指定对象
   *
   * @protected
   * @param {string} cls
   * @param {*} objNode
   * @param {string} strTag
   * @return {*}  {*}
   */
  protected getPSModel4(cls: string, objNode: any, strTag: string): IPSModelObject {
    return this.getPSModelService().getPSModel4(this, cls, objNode, strTag);
  }

  /**
   * 从模型数组中获取指定对象
   *
   * @param cls
   * @param list
   * @param objKey
   * @param bTryMode
   * @returns
   */
  protected getPSModel5(cls: string, list: any[] | null, objKey: any): IPSModelObject {
    return this.getPSModelService().getPSModel5(this, cls, list!, objKey);
  }

  /**
   * 填充数组模型
   *
   * @protected
   * @param {IModel[]} models
   * @param {string} cls
   * @return {*}  {IPSModelObject[]}
   */
  protected fillChildListModel(models: IModel[], cls: string): IPSModelObject[] | null {
    if (isNilOrEmpty(models)) {
      return null;
    }
    return models.map(item => {
      return this.getPSModel4(cls, item, '');
    });
  }

  getChildPSModelObject(cls: string, objNode: IModel, strTag: string): IPSModelObject {
    return this.getPSModelService().getChildPSModelObject(this, cls, objNode, strTag);
  }

  getParentPSModelObject(cls?: string): IPSModelObject {
    if (notNilEmpty(cls) && (notNilEmpty(this.parentModel) || this.parentModel!.instanceof(cls!) !== true)) {
      return this.getPSModelService().getParentPSModelObject(this, cls!);
    }
    return this.parentModel!;
  }
}
